package com.zto.sch.base.thread;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;
import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @program: sch-diy-parent
 * @description:
 * @author: sch
 * @create: 2021-06-07 17:18
 **/
public class FutureAndCallable {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1000));
        StopWatch stopWatch = new StopWatch("计时器");
        stopWatch.start();
        List<Future<String>> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            SyncCallable syncCallable = new SyncCallable(i);
            list.add(threadPoolExecutor.submit(syncCallable));
        }
        stopWatch.stop();
        System.out.println("共耗时:" + stopWatch.getTotalTimeMillis() + "ms");

        for (Future<String> future : list) {
            try {
                if (future.get().equals("success")) {
                    System.out.println("真正成功啦...");
                }
            } catch (Exception e) {
                System.out.println("失败....");
            }

        }
        threadPoolExecutor.shutdown();
    }


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static
    class SyncCallable implements Callable<String> {
        private int i;

        @Override
        public String call() throws Exception {
            if (i % 30 == 0) {
                Thread.sleep(1000);
                System.out.println("打印" + i);
                throw new RuntimeException("aaa");
            }
            return "success";
        }

    }


    @Test
    public void futureTest() {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("future1 finished!");
            return "future1 finished!";
        });
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("future2 finished!");
            return "future2 finished!";
        });
        CompletableFuture<Void> combindFuture = CompletableFuture.allOf(future1, future2);
        try {
//            combindFuture.get();
            combindFuture.join();

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("future1: " + future1.isDone() + " future2: " + future2.isDone());
    }
}
